/*
 * Powered By XY
 * Since 2020
 */

package com.xy.biz.xd.service.impl;

import com.xy.biz.base.client.DictClient;
import com.xy.biz.base.domain.req.ListDictItemRequest;
import com.xy.biz.base.domain.resp.ListDictItemResponse;
import com.xy.biz.fd.client.DocumentClient;
import com.xy.biz.fd.client.DocumentCodeRuleClient;
import com.xy.biz.fd.domain.req.document.GetDocumentRequest;
import com.xy.biz.fd.domain.req.document.ListDocumentRequest;
import com.xy.biz.fd.domain.req.documentCode.GetDocumentByCodeRequest;
import com.xy.biz.fd.domain.resp.GetDocumentResponse;
import com.xy.biz.fd.domain.utils.DocumentPropertyUtils;
import com.xy.biz.mc.domain.Message;
import com.xy.biz.mc.domain.consts.MessageTypeConstant;
import com.xy.biz.mc.domain.req.MessagePushRequest;
import com.xy.biz.ts.client.ExaminationRecordClient;
import com.xy.biz.ts.client.LearnRecordClient;
import com.xy.biz.ts.client.PracticeRecordClient;
import com.xy.biz.ts.client.TrainClient;
import com.xy.biz.ts.domain.req.ListLearnRecordRequest;
import com.xy.biz.ts.domain.req.ListPracticeRecordRequest;
import com.xy.biz.ts.domain.req.ListTrainRequest;
import com.xy.biz.ts.domain.req.examinationRecord.GetExaminationRecordByTrainIdRequest;
import com.xy.biz.ts.domain.resp.GetExaminationRecordResponse;
import com.xy.biz.ts.domain.resp.GetLearnRecordResponse;
import com.xy.biz.ts.domain.resp.GetPracticeRecordResponse;
import com.xy.biz.ts.domain.resp.GetTrainResponse;
import com.xy.biz.uc.client.UserClient;
import com.xy.biz.uc.client.UserGroupClient;
import com.xy.biz.uc.domain.dto.UserDTO;
import com.xy.biz.uc.domain.dto.UserGroupDTO;
import com.xy.biz.uc.domain.req.ListUserGroupByIdsRequest;
import com.xy.biz.uc.domain.resp.GetTeamUserResponse;
import com.xy.biz.xd.domain.bo.*;
import com.xy.biz.xd.domain.converter.DocumentFlowConverter;
import com.xy.biz.xd.domain.converter.DocumentFlowHandleConverter;
import com.xy.biz.xd.domain.converter.DocumentFlowHandleUserConverter;
import com.xy.biz.xd.domain.enums.DocumentFlowBatchTypeEnum;
import com.xy.biz.xd.domain.enums.DocumentFlowExistStatusEnum;
import com.xy.biz.xd.domain.enums.DocumentReleaseStatusEnum;
import com.xy.biz.xd.domain.query.*;
import com.xy.biz.xd.domain.req.*;
import com.xy.biz.xd.domain.resp.*;
import com.xy.biz.xd.manager.*;
import com.xy.biz.xd.service.DocumentFlowService;
import com.xy.biz.xd.service.DocumentReleaseService;
import com.xy.lang.domain.Page;
import com.xy.lang.domain.Result;
import com.xy.lang.util.CalendarUtils;
import com.xy.lang.util.ResultUtils;
import com.xy.tool.context.UserContextHolder;
import com.xy.tool.json.JsonUtils;
import com.xy.tool.util.BeanUtilsEx;
import lombok.extern.slf4j.Slf4j;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.apache.commons.collections4.Get;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.w3c.dom.Document;

import java.sql.ResultSet;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

import static com.xy.biz.xd.domain.bo.DocumentFlowConstants.*;
import static com.xy.biz.xd.domain.bo.DocumentFlowConstants.getPhaseName;
import static java.util.stream.Collectors.*;

/**
 * @author zsp
 * @date 2021-1-22
 */
@Slf4j
@Service
public class DocumentFlowServiceImpl implements DocumentFlowService, InitializingBean {

    @Autowired
    private DocumentFlowManager documentFlowManager;
    @Autowired
    private TaskService taskService;
    @Autowired
    private DocumentReleaseManager documentReleaseManager;
    @Autowired
    private DocumentFlowHandleUserManager documentFlowHandleUserManager;
    @Autowired
    private RuntimeService runtimeService;
    @Autowired
    private DocumentFlowCancelRequestFlowManager documentFlowCancelRequestFlowManager;
    @Autowired
    private DictClient dictClient;
    @Autowired
    private DocumentFlowServiceSupport documentFlowServiceSupport;
    @Autowired
    private DocumentFlowHandleManager documentFlowHandleManager;
    @Autowired
    private DocumentClient documentClient;
    @Autowired
    private UserClient userClient;
    @Autowired
    private UserGroupClient userGroupClient;
    @Autowired
    private DocumentReleaseService documentReleaseService;
    @Autowired
    private LearnRecordClient learnRecordClient;
    @Autowired
    private ExaminationRecordClient examinationRecordClient;
    @Autowired
    private TrainClient trainClient;
    @Autowired
    private PracticeRecordClient practiceRecordClient;
    @Autowired
    private DocumentFlowNewAndModifyManager documentFlowNewAndModifyManager;

    @Override
    public void afterPropertiesSet() throws Exception {

    }

    @Override
    public Result<?> deleteDocumentFlow(Long documentFlowId) {
        int affectedRows = documentFlowManager.deleteDocumentFlow(documentFlowId);
        if (affectedRows > 0) {
            return Result.success();
        }
        return Result.ofErrorRowsAffected();
    }

    @Override
    public DocumentFlowBO getDocumentFlow(Long documentFlowId) {
        return documentFlowManager.getDocumentFlow(documentFlowId);
    }

    @Override
    public List<DocumentFlowBO> listDocumentFlowById(Collection<Long> collection) {
        return documentFlowManager.listDocumentFlowById(collection);
    }

    @Override
    public List<DocumentFlowBO> listDocumentFlow(DocumentFlowQuery query) {
        List<DocumentFlowBO> documentFlowBOS = documentFlowManager.listDocumentFlow(
                query.addBatchType(DocumentFlowBatchTypeEnum.UNBATCH.getCode())
                        .addBatchType(DocumentFlowBatchTypeEnum.BATCH_PARENT.getCode()));
        //在Handel表中查找已取消、终止、发行 的流程文件不允许申请“取消申请流程”
        Set<Long> documentFlowIds = documentFlowBOS.stream().map(DocumentFlowBO::getDocumentFlowId).collect(toSet());
        List<String> phases = new ArrayList<>();
        phases.add(PHASE_RELEASE);
        phases.add(PHASE_AGREE_CANCEL);
        phases.add(PHASE_END);
        Set<Long> dfhIds = documentFlowHandleManager.listDocumentFlowHandle(DocumentFlowHandleQuery.max().documentFlowIdS(documentFlowIds).phases(phases).build()).stream().map(DocumentFlowHandleBO::getDocumentFlowId).collect(toSet());
        documentFlowBOS.sort((m1, m2) -> m2.getCreateTime().compareTo(m1.getCreateTime()));
        documentFlowBOS = documentFlowBOS.stream()
                .peek(doc -> {
                    doc.setAccessTimeString(CalendarUtils.getDeadlineString(doc.getCreateTime(), LocalDateTime.now()));
                    if (dfhIds.contains(doc.getDocumentFlowId())) {
                        doc.setCancelFlag(false);
                    } else {
                        doc.setCancelFlag(true);
                    }
                })
                .collect(Collectors.toList());
        return documentFlowBOS;
    }

    @Override
    public List<DocumentFlowBO> listDocumentFlow2(DocumentFlowQuery query) {
        List<DocumentFlowBO> documentFlowBOS = documentFlowManager.listDocumentFlow(
                query);
        if (!CollectionUtils.isEmpty(documentFlowBOS)) {
            List<GetDocumentResponse> documentList = ResultUtils.get(documentClient.listDocumentById(
                    documentFlowBOS.stream().map(DocumentFlowBO::getDocumentId).collect(Collectors.toSet())));
            if (!CollectionUtils.isEmpty(documentList)) {
                Map<Long, GetDocumentResponse> documentMap = documentList.stream().collect(Collectors.toMap(GetDocumentResponse::getDocumentId, e -> e));
                documentFlowBOS.forEach(e -> {
                    GetDocumentResponse document = documentMap.get(e.getDocumentId());
                    if (!Objects.isNull(document)) {
                        e.setFileExtension(document.getFileExtension());
                    }
                });
            }
        }
        return documentFlowBOS;
    }

    /**
     * 查找台账数据
     *
     * @param query 查找条件
     */
    @Override
    public Page<GetDocumentFlowResponse> listLedgerData(DocumentFlowQuery query) {
        Integer startIndex = query.getOffset();
        Integer endIndex = startIndex + query.getRows();
        //获取全部流程数据
        List<DocumentFlowBO> documentFlowBOS = documentFlowManager.listDocumentFlow(DocumentFlowQuery.max().documentFlowId(query.getDocumentFlowId()).build());
        //获取全部取消流程数据，根据flowId分类，去重
        Map<Long, List<DocumentFlowCancelRequestFlowBO>> map = documentFlowCancelRequestFlowManager.listDocumentFlowCancelRequestFlow(DocumentFlowCancelRequestFlowQuery.max().cancelRequestFlowId(query.getDocumentFlowId()).build()).stream().collect(Collectors.groupingBy(DocumentFlowCancelRequestFlowBO::getDocumentFlowId));
        if (CollectionUtils.isEmpty(documentFlowBOS) && CollectionUtils.isEmpty(map)) {
            return new Page<>(null, 0);
        }
        List<DocumentFlowCancelRequestFlowBO> cancelRequestFlowBOList = new ArrayList<>();
        map.forEach((key, value) -> {
            value.sort(Comparator.comparing(DocumentFlowCancelRequestFlowBO::getUpdateTime).reversed());
            if (!CollectionUtils.isEmpty(value)) {
                cancelRequestFlowBOList.add(value.get(0));
            }
        });
        cancelRequestFlowBOList.sort(Comparator.comparing(DocumentFlowCancelRequestFlowBO::getUpdateTime));
        List<GetDocumentFlowResponse> documentFlowResponses = DocumentFlowConverter.toResponse(documentFlowBOS);
        buildGetDocumentFlowResponse(documentFlowResponses);
        documentFlowResponses.addAll(buildCancel(cancelRequestFlowBOList, documentFlowResponses));
        // TODO 临时，需重构
        if (Objects.nonNull(query.getDocumentCode())) {
            documentFlowResponses = documentFlowResponses.stream().filter(d -> query.getDocumentCode().equals(d.getDocumentCode())).collect(toList());
        }
        final int count = documentFlowResponses.size();
        endIndex = documentFlowResponses.size() < endIndex ? documentFlowResponses.size() : endIndex;
        documentFlowResponses = documentFlowResponses.subList(startIndex, endIndex);
        userClient.buildByUser(documentFlowResponses,
                documentFlowResponses.stream().map(GetDocumentFlowResponse::getCreateUserId).collect(toSet()),
                GetDocumentFlowResponse::getCreateUserId,
                (d, userDTO) -> d.setCreateUserName(userDTO.getUserName()));
        //部门名
        Set<Long> userIds = documentFlowResponses.stream().map(GetDocumentFlowResponse::getCreateUserId).collect(toSet());
        Map<Long, UserDTO> collect = ResultUtils.get(userClient.listUserById(userIds)).stream().collect(Collectors.toMap(UserDTO::getUserId, u -> u));
        documentFlowResponses.forEach(d -> {
            UserDTO userDTO = collect.get(d.getCreateUserId());
            if (Objects.nonNull(userDTO)) {
                d.setCreateUserGroupName(userDTO.getUserGroup().getName());
            }
        });
        documentFlowResponses.sort(Comparator.comparing(GetDocumentFlowResponse::getUpdateTime).reversed());
        return new Page<>(documentFlowResponses, count);
    }

    @Override
    public int countDocumentFlow(DocumentFlowQuery query) {
        return documentFlowManager.countDocumentFlow(query);
    }


    // 查询当前的流程任务
    @Override
    public Page<GetDocumentFlowResponse> searchDocumentFlowTodo(DocumentFlowQuery query) {
        List<DocumentFlowBO> documentFlowBOList = new ArrayList<>();
        List<DocumentFlowCancelRequestFlowBO> documentFlowCancelRequestFlowBOList = new ArrayList<>();
        List<String> flow = new ArrayList<>();
        flow.add(PROCESS_NEW_FLOW);
        flow.add(PROCESS_MODIFY_FLOW);
        flow.add(PROCESS_COMMON_FLOW);
        flow.add(PROCESS_CANCEL_REQUEST);
        //改变处理人
        //taskService.setAssignee("50144", "17");
        long total = taskService.createTaskQuery()
                .taskAssignee(UserContextHolder.getUserId().toString())
                .processDefinitionKeyIn(flow)
                .count();
        if (total > 0) {
            List<Task> taskList = taskService.createTaskQuery()
                    .taskAssignee(UserContextHolder.getUserId().toString())
                    .processDefinitionKeyIn(flow)
                    .orderByTaskCreateTime()
                    .desc()
                    .listPage(query.getOffset(), query.getRows());
            if (!CollectionUtils.isEmpty(taskList)) {
                // TODO 此函数用于强制删除任务
//                taskList.forEach(e -> {
//                    if (e.getId().equals("57621") || e.getId().equals("57633")) {
//                        taskService.complete(e.getId());
//                        taskService.deleteTask(e.getId(), true);
//                    }
//                });

                Set<String> processInstanceIdSet = taskList.stream().map(Task::getProcessInstanceId).collect(toSet());
                List<ProcessInstance> processInstanceList = runtimeService.createProcessInstanceQuery().processInstanceIds(processInstanceIdSet).list();
                Set<Long> documentFlowIdSet = processInstanceList.stream().map(e -> Long.parseLong(e.getBusinessKey())).collect(toSet());
                documentFlowBOList = documentFlowManager.listDocumentFlowById(documentFlowIdSet);
                documentFlowCancelRequestFlowBOList = documentFlowCancelRequestFlowManager.listDocumentFlowCancelRequestFlowById(documentFlowIdSet);
            }
        }
        documentFlowBOList = documentFlowBOList.stream()
                .peek(doc -> doc.setAccessTimeString(CalendarUtils.getDeadlineString(doc.getUpdateTime(), LocalDateTime.now())))
                .collect(Collectors.toList());
        List<GetDocumentFlowResponse> list = DocumentFlowConverter.toResponse(documentFlowBOList);
        buildGetDocumentFlowResponse(list);
        List<GetDocumentFlowResponse> documentFlowResponses = null;
        if (!CollectionUtils.isEmpty(documentFlowCancelRequestFlowBOList)) {
            documentFlowResponses = buildCancel(documentFlowCancelRequestFlowBOList, list);
        }
        List<GetDocumentFlowResponse> documentFlowResponseList = new ArrayList<>(list);
        if (!CollectionUtils.isEmpty(documentFlowResponses)) {
            documentFlowResponseList.addAll(documentFlowResponses);
        }
        Collections.sort(documentFlowResponseList, Comparator.comparing(GetDocumentFlowResponse::getUpdateTime).reversed());
        return new Page(documentFlowResponseList, (int) total);
    }

    @Override
    public int pageTodoDocumentFlowCount() {
        return (int) taskService.createTaskQuery()
                .taskAssignee(UserContextHolder.getUserId().toString())
                .count();
    }

    /**
     * 判断有无相同流程
     * @param request
     * @return
     */
    @Override
    public Result<?> getFlowExist(GetDocumentFlowExistRequest request) {
        DocumentReleaseBO documentRelease = documentReleaseManager.getDocumentRelease(DocumentReleaseQuery.one().documentCode(request.getDocumentCode()).status(DocumentReleaseStatusEnum.RELEASE.getCode()).build());
        if (Objects.isNull(documentRelease)) {
            return Result.success(DocumentFlowExistStatusEnum.INVALID.getCode());
        }
        if (Objects.nonNull(documentRelease) && !documentRelease.getEffectFlag()) {
            return Result.success(DocumentFlowExistStatusEnum.INEXISTENCE.getCode());
        }
        return getExit(request.getDocumentCode(), request.getFlowType());
    }

    @Override
    public Result<?> saveHandleUser(Collection<DocumentFlowHandleUserBO> collection) {
        userClient.buildByUser(collection,
                collection.stream().map(DocumentFlowHandleUserBO::getHandleUserId).collect(Collectors.toSet()),
                DocumentFlowHandleUserBO::getHandleUserId,
                (handleUser, userDTO) -> handleUser.setHandleUserName(userDTO.getUserName()));
        collection.forEach(e -> {
            e.setCreateUserId(UserContextHolder.getUserId());
            e.setCreateUserName(UserContextHolder.getUserName());
            e.setTenantId(UserContextHolder.getTenantId());
            e.setCreateTime(LocalDateTime.now());
            e.setUpdateTime(LocalDateTime.now());
            e.setDeleteFlag(false);
        });
        int row = documentFlowHandleUserManager.saveAllDocumentFlowHandleUser(collection);
        if (row > 0) {
            return Result.success();
        }
        return Result.ofErrorRowsAffected();
    }

    @Override
    public Result<List<GetDocumentFlowHandleUserResponse>> listHandleUser(DocumentFlowHandleUserQuery query) {
        return Result.success(DocumentFlowHandleUserConverter.toResponse(documentFlowHandleUserManager.listDocumentFlowHandleUser(query)));
    }

    /**
     * 获取生效处理所有文件信息
     * @param request
     * @return
     */
    @Override
    public Result<DocumentAllInfoResponse> getDocumentAllInfo(GetDocumentFlowRequest request) {
        DocumentAllInfoResponse documentAllInfoResponse = new DocumentAllInfoResponse();
        DocumentFlowBO documentFlow = documentFlowManager.getDocumentFlow(request.getDocumentFlowId());
        if (Objects.isNull(documentFlow)) {
            return Result.ofNotFound();
        }
        //文件信息
        GetDocumentResponse document = ResultUtils.get(documentClient.getDocument(GetDocumentRequest.builder().documentId(documentFlow.getDocumentId()).build()));
        document.setLevelString(DocumentPropertyUtils.getLevel(document.getType()));
        document.setPropertyString(DocumentPropertyUtils.getProperty(document.getType()));

        if (documentFlow.getBatchType().equals(DocumentFlowBatchTypeEnum.BATCH_SUBFILE.getCode())) {
            documentFlow = documentFlowManager.getDocumentFlow(documentFlow.getParentDocumentFlowId());
        }

        List<GetDocumentFlowResponse> getDocumentFlowResponses = new ArrayList<>();
        List<DocumentFlowHandleBO> documentFlowHandleBOS = documentFlowHandleManager.listDocumentFlowHandle(DocumentFlowHandleQuery.builder().documentFlowId(documentFlow.getDocumentFlowId()).build());
        //流程信息
        GetDocumentFlowResponse getDocumentFlowResponse = DocumentFlowConverter.toResponse(documentFlow);
        getDocumentFlowResponses.add(getDocumentFlowResponse);
        buildGetDocumentFlowResponse(getDocumentFlowResponses);
        //流程节点处理记录
        List<GetDocumentFlowHandleResponse> getDocumentFlowHandleResponses = DocumentFlowHandleConverter.toResponse(documentFlowHandleBOS);
        userClient.buildByUser(getDocumentFlowHandleResponses,
                getDocumentFlowHandleResponses.stream().map(GetDocumentFlowHandleResponse::getHandleUserId).collect(toSet()),
                GetDocumentFlowHandleResponse::getHandleUserId,
                (dfh, userDTO) -> dfh.setHandleUserName(userDTO.getUserName()));
        userGroupClient.buildByUserGroup(getDocumentFlowHandleResponses,
                getDocumentFlowHandleResponses.stream().map(GetDocumentFlowHandleResponse::getHandleUserGroupId).collect(toSet()),
                GetDocumentFlowHandleResponse::getHandleUserGroupId,
                (dfh, userDTO) -> dfh.setHandleUserGroupName(userDTO.getUserGroupName()));
        getDocumentFlowHandleResponses = getDocumentFlowHandleResponses.stream().peek(d -> d.setPhaseName(DocumentFlowConstants.getPhaseName(d.getFlowType(), d.getPhase()))).collect(toList());
        //签收状态记录
        GetDocumentReleaseStatusResponse getDocumentReleaseStatusResponse =
                (GetDocumentReleaseStatusResponse) ResultUtils.get(
                        documentReleaseService.DocumentReleaseCheck(
                                GetDocumentReleaseCheckStatusRequest.builder().documentFlowId(request.getDocumentFlowId()).build()));
        //培训记录
        List<GetTrainResponse> trainResponses = ResultUtils.get(trainClient.listTrainByFlow(ListTrainRequest.builder().documentFlowId(documentFlow.getDocumentFlowId()).withUserGroup(true).withUser(true).build()));
        Set<Long> collect = null;
        if (!CollectionUtils.isEmpty(trainResponses)) {
            collect = trainResponses.stream().map(GetTrainResponse::getTrainId).collect(toSet());
        }
        List<GetLearnRecordResponse> getLearnRecordResponses = null;
        List<GetExaminationRecordResponse> examinationRecordResponses = null;
        List<GetPracticeRecordResponse> practiceRecordResponses = null;
        if (!CollectionUtils.isEmpty(collect)) {
            //自学记录
            getLearnRecordResponses = ResultUtils.get(learnRecordClient.pageLearnRecord(ListLearnRecordRequest.builder().getAllFlag(true).trainIds(collect).build())).getRows();
            //考试记录
            examinationRecordResponses = ResultUtils.get(examinationRecordClient.listExaminationRecordByTrainId(GetExaminationRecordByTrainIdRequest.builder().trainIds(collect).build()));
            //实操记录
            practiceRecordResponses = ResultUtils.get(practiceRecordClient.listPracticeRecord(ListPracticeRecordRequest.builder().trainIds(collect).build()));
        }
        documentAllInfoResponse.setDocumentResponse(document);
        documentAllInfoResponse.setLearnRecordResponses(getLearnRecordResponses);
        documentAllInfoResponse.setDocumentFlowResponse(getDocumentFlowResponse);
        documentAllInfoResponse.setDocumentFlowHandleResponses(getDocumentFlowHandleResponses);
        documentAllInfoResponse.setDocumentReleaseStatusResponse(getDocumentReleaseStatusResponse);
        documentAllInfoResponse.setTrainResponses(trainResponses);
        documentAllInfoResponse.setExaminationRecordResponses(examinationRecordResponses);
        documentAllInfoResponse.setPracticeRecordResponses(practiceRecordResponses);
        return Result.success(documentAllInfoResponse);
    }

    @Override
    public Result<List<UserDTO>> listAssignee(Long documentFlowId) {
        DocumentFlowBO documentFlowBO = documentFlowManager.getDocumentFlow(documentFlowId);
        if (!Objects.isNull(documentFlowBO)) {
            List<Long> userIdList = documentFlowServiceSupport.listAssignee(documentFlowBO);
            if (!CollectionUtils.isEmpty(userIdList)) {
                return userClient.listUserById(userIdList);
            }
        }
        return Result.success(Collections.emptyList());
    }

    private List<GetDocumentFlowResponse> buildCancel(List<DocumentFlowCancelRequestFlowBO> cancelRequestList, List<GetDocumentFlowResponse> getDocumentFlowResponse) {
        List<GetDocumentFlowResponse> documentFlowResponses = new ArrayList<>();
        //获取取消流程的原文档流程Id
        Set<Long> flowId = cancelRequestList.stream().map(DocumentFlowCancelRequestFlowBO::getDocumentFlowId).collect(toSet());
        //从当前待处理中查找是否包含
        List<GetDocumentFlowResponse> contains = getDocumentFlowResponse.stream().filter(d -> flowId.contains(d.getDocumentId())).collect(toList());
        Set<Long> containsId = contains.stream().map(GetDocumentFlowResponse::getDocumentFlowId).collect(toSet());
        //未命中的Id
        Set<Long> residue = flowId.stream().filter(item -> !containsId.contains(item)).collect(toSet());
        List<GetDocumentFlowResponse> getDocumentFlowResponses = new ArrayList<>();
        if (!CollectionUtils.isEmpty(residue)) {
            getDocumentFlowResponses = DocumentFlowConverter.toResponse(documentFlowManager.listDocumentFlowById(residue));
        }
        documentFlowResponses.addAll(contains);
        documentFlowResponses.addAll(getDocumentFlowResponses);
        Map<Long, DocumentFlowCancelRequestFlowBO> map = cancelRequestList.stream().collect(toMap(DocumentFlowCancelRequestFlowBO::getDocumentFlowId, c -> c));
        documentFlowResponses = documentFlowResponses.stream().peek(d -> {
            DocumentFlowCancelRequestFlowBO dc = map.get(d.getDocumentFlowId());
            d.setCreateTime(dc.getCreateTime());
            d.setUpdateTime(dc.getUpdateTime());
            d.setAccessTimeString(CalendarUtils.getDeadlineString(dc.getUpdateTime(), LocalDateTime.now()));
            d.setFlowType(dc.getFlowType());
            d.setPhase(PHASE_CONTENT_AUDIT);
            d.setPhaseName(getPhaseName(dc.getFlowType(), PHASE_CONTENT_AUDIT));
            d.setFlowTypeName(getFlowTypeMap().get(dc.getFlowType()));
            d.setReason(dc.getReason());
            d.setCreateUserId(dc.getCreateUserId());
            d.setUrgent("1");
            d.setUrgentName("紧急");
            d.setTenantId(dc.getTenantId());
        }).collect(toList());
        return documentFlowResponses;
    }

    private Result<?> getExit(String documentCode, Integer flowType) {
        //return   1:流程不存在 2:流程已存在 3：流程尚未生效
        List<DocumentFlowBO> documentFlowBOList = documentFlowManager.listDocumentFlow(
                DocumentFlowQuery.max().flowType(flowType).documentCode(documentCode).build()
                        .addFlowType(FLOW_TYPE_DROP).addFlowType(FLOW_TYPE_MODIFY));
        if (CollectionUtils.isEmpty(documentFlowBOList)) {
            return Result.success(DocumentFlowExistStatusEnum.INVALID.getCode());
        }
        documentFlowBOList.removeIf(e ->
                e.getPhase().equals(PHASE_END) || e.getPhase().equals(PHASE_REJECT));
        if (!CollectionUtils.isEmpty(documentFlowBOList)
                && !documentFlowBOList.stream().allMatch(e -> e.getPhase().equals(PHASE_RELEASE))) {
            return Result.success(DocumentFlowExistStatusEnum.EXISTENCE.getCode());
        }
        List<DocumentFlowBO> releaseFlow = documentFlowBOList.stream().filter(e -> e.getPhase().equals(PHASE_RELEASE)).collect(toList());
        if (!CollectionUtils.isEmpty(releaseFlow)) {
            Set<Long> documentFlowIdSet = releaseFlow.stream().map(DocumentFlowBO::getDocumentFlowId).collect(toSet());
            Set<Long> existedDocumentFlowIdSet = documentFlowHandleManager.listDocumentFlowHandle(
                            DocumentFlowHandleQuery.max()
                                    .documentFlowIdS(documentFlowIdSet)
                                    .build())
                    .stream().filter(e -> e.getPhase().equals(PHASE_RELEASE)).map(DocumentFlowHandleBO::getDocumentFlowId)
                    .collect(toSet());
            if (!existedDocumentFlowIdSet.containsAll(documentFlowIdSet)) {
                return Result.success(DocumentFlowExistStatusEnum.EXISTENCE.getCode());
            }
        }
        return Result.success(DocumentFlowExistStatusEnum.INVALID.getCode());
    }

    private Map<Integer, String> getFlowTypeMap() {
        List<ListDictItemResponse> listDictItemResponseList
                = ResultUtils.get(dictClient.listDictItem(ListDictItemRequest.builder().dictGroupCode("flow_type").build()));
        Map<Integer, String> flowTypeMap = new HashMap<>();
        if (!CollectionUtils.isEmpty(listDictItemResponseList)) {
            try {
                listDictItemResponseList.forEach(e -> flowTypeMap.put(Integer.parseInt(e.getDictCode()), e.getDictValue()));
            } catch (Exception e) {
                log.error("流程类型编码转换错误", e);
            }
        }
        return flowTypeMap;
    }

    private void buildGetDocumentFlowResponse(List<GetDocumentFlowResponse> list) {
        if (!CollectionUtils.isEmpty(list)) {
            Map<Integer, String> flowTypeMap = getFlowTypeMap();
            for (GetDocumentFlowResponse getDocumentFlowResponse : list) {
                getDocumentFlowResponse.setFlowTypeName(flowTypeMap.get(getDocumentFlowResponse.getFlowType()));
                getDocumentFlowResponse.setPhaseName(getPhaseName(getDocumentFlowResponse.getFlowType(), getDocumentFlowResponse.getPhase()));
                if (Objects.equals(URGENT_NORMAL, getDocumentFlowResponse.getUrgent())) {
                    getDocumentFlowResponse.setUrgentName("正常");
                } else if (Objects.equals(URGENT_URGENT, getDocumentFlowResponse.getUrgent())) {
                    getDocumentFlowResponse.setUrgentName("紧急");
                } else {
                    getDocumentFlowResponse.setUrgentName(getDocumentFlowResponse.getUrgent());
                }
            }
        }
    }

}
